package org.itzixi.netty.websocket;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * Http初始化器 chanel注册后会执行里面的相应方法
 */
public class WSServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel channel) throws Exception {
        // 通过SocketChannel去获得对应的管道
        ChannelPipeline pipeline = channel.pipeline();
        /*
         * 通过管道添加handler
         */
        // HttpServerCodec是由netty自己提供的助手类，可以理解为拦截器
        // 当请求到服务端时，我们需要做解码，当服务端有响应时，我们需要做编码
        // websocket 基于http,所以需要有http编解码器
        pipeline.addLast( new HttpServerCodec()); // Http编解码器

        // 用于处理大数据流
        pipeline.addLast(new ChunkedWriteHandler());

        // http消息聚合器，将多个消息聚合到一个FullHttpRequest或FullHttpResponse中
        // netty编程中几乎都会使用
        pipeline.addLast(new HttpObjectAggregator(1024 * 64));

        //=============================以上是用于支持http协议的相关handler===========================

        //=============================增加心跳支持 start===========================

        // 针对客户端，如果在1分钟内没有向服务端发送读写心跳(ALL)，则主动断开连接
        // 如果是读空闲或写空闲，不做任何处理
        pipeline.addLast(new IdleStateHandler(8, 10, 300 * 60));
        // 自定义的空闲状态检测
        pipeline.addLast(new HeartBeatHandler());

        //=============================增加心跳支持 end===========================

        //=============================以下是用于支持websocket===========================

        /**
         * websocket 服务器处理的协议，用于支持websocket，指定客户端访问路由：/ws
         * 处理一些比较繁重的操作
         * 会处理握手动作：handshaking(close, ping, pong) ping + pong = 心跳
         */
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
        // 自定义助手类，返回"Hello Netty ~"
        pipeline.addLast(new ChatHandler_Single());
    }
}
